package com.tcs.teg.service.accounts.impl;

import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.stat.Statistics;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.tcs.teg.dao.accounts.IAccountDao;
import com.tcs.teg.domain.accounts.Account;
import com.tcs.teg.domain.accounts.AccountCriteria;
import com.tcs.teg.domain.accounts.AccountRegistrationForm;
import com.tcs.teg.service.accounts.IAccountService;
import com.tcs.teg.utils.common.NoDataFoundException;
import common.money.Percentage;


public class AccountServiceImpl implements IAccountService {
	
	private static final Log logger = LogFactory.getLog(AccountServiceImpl.class);

	private IAccountDao accountDao;
	
	public AccountServiceImpl(){}
	
	public AccountServiceImpl(IAccountDao accountDao){
		this.accountDao = accountDao;
	}
	
	@Transactional	
	public List<Account> getAllAccounts() {
		logger.debug("INSTANCE .................................. "+this);
		return accountDao.getAllAccounts();
	}
	
	@Transactional	
	public List<String> getAccountNames(String searchStr) {
		logger.debug("INSTANCE .................................. "+this);
		return accountDao.getAccountNames(searchStr);
	}
	
	@Transactional	
	public List<String> getContactNumbers(String searchStr) {
		logger.debug("INSTANCE .................................. "+this);
		return accountDao.getContactNumbers(searchStr);
	}


	@Transactional(propagation=Propagation.REQUIRES_NEW)
	public Account getAccount(Integer entityId) throws ObjectRetrievalFailureException{
		logger.debug("INSTANCE .................................. "+this);
		if (logger.isDebugEnabled()) {
			logger.debug("got the account details -------------------");
		}	
		Account acc = accountDao.getAccount(entityId);
		return acc;	
	}

	//@Transactional
	public void update(Account account) {
		if (logger.isDebugEnabled()) {
			logger.debug("updating the account in service -------------------"+account);
		}	
		accountDao.update(account);	
	}

	@Transactional
	public void updateBeneficiaryAllocationPercentages(Integer accountId, Map<String, Percentage> allocationPercentages) {
		accountDao.updateBeneficiaryAllocationPercentages(accountId,allocationPercentages);
	}

	@Transactional
	public void addBeneficiary(Integer accountId, String beneficiaryName) {
		accountDao.addBeneficiary(accountId, beneficiaryName);		
	}

	@Transactional
	public void removeBeneficiary(Integer accountId, String beneficiaryName, Map<String, Percentage> allocationPercentages) {
		accountDao.removeBeneficiary(accountId, beneficiaryName, allocationPercentages);
	}

	
	@Transactional
    public List<Account> search(AccountCriteria criteria) {
		logger.debug("INSTANCE .................................. "+this);
		List<Account> accountList = accountDao.search(criteria);
		if (logger.isDebugEnabled()) {
			logger.debug("Account List after search -------------------");
		}
		if(accountList == null || accountList.size()==0) throw new NoDataFoundException("No Data Found");
		return accountList;
    }
	
	@Transactional
    public void saveRegistrationDetails(AccountRegistrationForm arf) {
		if (logger.isDebugEnabled()) {
			logger.debug("Account Registration -------------------"+arf.getBeneficiaries());
		}		
		//save Account
		Account account = new Account();
		//save Account Credit Card details
		account.setName(arf.getAccountName());
		account.setContactNumber(arf.getContactNumber());
		account.setCreditCardNumber(arf.getCreditCardNumber());
		account.setBeneficiaries(arf.getBeneficiaries());
		accountDao.createAccount(account);
	
    }
	
	public Statistics getStatistics(){
		return accountDao.getStatistics();		
	}
}
